<?php

class ArrayToDropDownList extends CWidget {

    public $model;
    public $attribute;
    public $data;
    public $parentId = 0;
    public $disableParent = false; // true: sẽ vô hiệu những option là cha
    public $selected; //option nào có value = $select sẽ được chọn
    public $disableItem; //option nào có value = $disableItem sẽ bị disable
    public $emptyOption;
    public $htmlOptions;

    public function run() {
        $fieldName = get_class($this->model) . "[$this->attribute]";

        $htmlOptions = array(
            'name'       => $fieldName,
            'id'         => $fieldName,
            'class'      => 'select',
        );
        if (is_array($this->htmlOptions))
            $htmlOptions = array_merge($htmlOptions, $this->htmlOptions);

        echo CHtml::openTag('select', $htmlOptions);

        if (!empty($this->emptyOption))
            echo "<option value=\"\">$this->emptyOption</option>";

        $this->menuRecursion($this->data, $this->parentId);
        echo CHtml::closeTag('select');
    }

    /**
     * DÙNG ĐỆ QUI - RECURSION
     */
    function menuRecursion($data, $parent_id) {
        $parent_array = $data[$parent_id];

        foreach ($parent_array as $id => $title) {
            //Default value
            $attr = 'value="' . $id . '"';

            if ((!empty($this->selected) && ($id == $this->selected)))
                $attr .= ' selected="selected"';

            if ((!empty($this->disableItem) && ($id == $this->disableItem)))
                $attr .= ' disabled="disabled"';
            //===== end of default value =====

            if (array_key_exists($id, $data)) {
                $attr .= ' class="parent"';

                if ($this->disableParent)
                    $attr .= ' disabled="disabled"';

                echo '<option ' . $attr . '>' . $this->calLevel($id) . $title . '</option>';

                $this->menuRecursion($data, $id);
            }
            else {
                echo '<option ' . $attr . '>' . $this->calLevel($id) . $title . '</option>';
            }
        }
    }

    /**
     * Tính toán level của item hiện hành
     * @param integer $id
     * @return char Example: null for level 1, '-' for level 2, '--'...
     */
    private function calLevel($id) {
        $level = '';

        $parentId = $this->findParentId($id);
        while ($parentId != 0) {
            $level .= ' - ';
            $parentId = $this->findParentId($parentId);
        }

        return $level;
    }

    /**
     * Find parent_id of the item
     * @param integer $id
     * @return integer
     */
    private function findParentId($id) {
        $data  = $this->data;
        $found = false;

        foreach ($data as $key => $items)
            if (array_key_exists($id, $items))
                $found = $key;

        return $found;
    }

}

?>